﻿using System.Web.Security;
using System;

namespace GiveAQuiz.Web.Membership
{
  /// <summary>
  /// This class implements the IMembershipService 
  /// interface by using the ASP.Net MembershipProvider 
  /// implementation.
  /// </summary>
  public class AccountMembershipService : IMembershipService
  {
    private MembershipProvider _provider;

    /// <summary>
    /// Creates an instance of the AccountMembershipService 
    /// object using the requested MembershipProvider 
    /// implementation.
    /// </summary>
    /// <param name="provider">The MembershipProvider implementation.</param>
    public AccountMembershipService(MembershipProvider provider)
    {
      _provider = provider ?? System.Web.Security.Membership.Provider;
    }

    /// <summary>
    /// Gets the minimum password length as configured in the 
    /// MembershipProvider.
    /// </summary>
    public int MinPasswordLength
    {
      get
      {
        return _provider.MinRequiredPasswordLength;
      }
    }

    /// <summary>
    /// Gets the MembershipUser that is currently signed in
    /// (if one exists)
    /// </summary>
    public MembershipUser CurrentUser
    {
      get { return System.Web.Security.Membership.GetUser(); }
    }

    /// <summary>
    /// Retrieve a user based on their user name.
    /// </summary>
    /// <param name="userName">The user name to search for.</param>
    /// <returns>The corresponding MembershipUser.</returns>
    public MembershipUser GetUser(string userName)
    {
      return _provider.GetUser(userName, false);
    }

    /// <summary>
    /// Retrieve a user based on their email.
    /// </summary>
    /// <param name="email">The email to search for.</param>
    /// <returns>The corresponding MembershipUser.</returns>
    public MembershipUser GetUserByEmail(string email)
    {
      string userName = _provider.GetUserNameByEmail(email);
      if (!String.IsNullOrEmpty(userName))
      {
        return _provider.GetUser(userName, false);
      }
      return null;
    }

    /// <summary>
    /// Validate a User based on their user name and password.
    /// </summary>
    /// <param name="userName">The user name.</param>
    /// <param name="password">The password.</param>
    /// <returns>true if the user can be validated; otherwise false.</returns>
    public bool ValidateUser(string userName, string password)
    {
      return _provider.ValidateUser(userName, password);
    }

    /// <summary>
    /// Create a User.
    /// </summary>
    /// <param name="userName">The desired user name.</param>
    /// <param name="password">The requested password.</param>
    /// <param name="email">The user's email address.</param>
    /// <returns>An MembershipCreateStatus enumeration containing
    /// the response code.</returns>
    public MembershipCreateStatus CreateUser(string userName, string password, string email)
    {
      MembershipCreateStatus status;
      _provider.CreateUser(userName, password, email, null, null, true, null, out status);
      return status;
    }

    /// <summary>
    /// Change the password for a given User.
    /// </summary>
    /// <param name="userName">The user name requesting the password change.</param>
    /// <param name="oldPassword">The user's original password.</param>
    /// <param name="newPassword">The requested new password.</param>
    /// <returns>true if the password was successfully changed; 
    /// otherwise false.</returns>
    public bool ChangePassword(string userName, string oldPassword, string newPassword)
    {
      MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
      return currentUser.ChangePassword(oldPassword, newPassword);
    }

    /// <summary>
    /// Resets the password for a User.
    /// </summary>
    /// <param name="userName">The user name.</param>
    /// <returns>The new password.</returns>
    public string ResetPassword(string userName)
    {
      return _provider.ResetPassword(userName, null);
    }

    /// <summary>
    /// Update a User.
    /// </summary>
    /// <param name="user">The User to update.</param>
    public void UpdateUser(MembershipUser user) 
    {
      _provider.UpdateUser(user);
    }
  }
}